package com.adee.juc;

import com.adee.util.Utils;

/**
 * 多线程设计模式：保护性暂停
 * 一个线程等待另一个线程执行结果，使用一个中间对象GuardedObject作为桥梁，可以传递结果数据，就可以使用保护性暂停模式。
 * 使用wait/notify实现保护性暂停模式，两个线程间通信。
 *
 * 如下例子，Thread-1阻塞等待获取Thread-2的计算结果，然后再继续执行
 */
public class Test001_WaitNotify {
    public static void main(String[] args) {
        final GuardedObject go = new GuardedObject();
        Thread t1 = new Thread(() -> {
            Object resp = go.get();
            System.out.println("获取结果：" + resp);
        }, "Thread-1");
        Thread t2 = new Thread(() -> {
            go.complete("occurrence");
        }, "Thread-2");
        t1.start();
        Utils.sleep(3);
        t2.start();
    }


    static class GuardedObject {
        private Object response;

        public synchronized Object get() {
            System.out.println(Thread.currentThread().getName() + " 尝试获取结果");
            while (response == null) {
                try {
                    System.out.println(Thread.currentThread().getName() + " 没获取到结果，阻塞等待");
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            return response;
        }

        public synchronized void complete(Object response) {
            this.response = response;
            notifyAll();
            System.out.println(Thread.currentThread().getName() + " 产生结果，并唤醒等待线程");
        }
    }
}
